package org.moonshot.cvm;

import java.util.HashMap;

public class CVMBlockClass extends CVMClass
{
	private static final HashMap<String, METHOD> methods = new HashMap<String, METHOD> ();
	
	private static enum METHOD {
		DO_0("do"), DO_1("do:"), DO_USE("doUsing:"),
		IF_T("ifTrue:"), IF_F("ifFalse:"), IF_TF("ifTrue:ifFalse:"), IF_FT("ifFalse:ifTrue:"),
		WHILE_T("whileTrue:"), WHILE_F("whileFalse:"), UNTIL_T("doUntil:"), UNTIL_F("doWhile:");
		
		METHOD(String name)
		{
			methods.put(name, this);
		}
	}
	
	public Object callInstance (ChattyVM aVM, Object aInstance, String aMethod, ChattyStack aStack, int nParams)
		throws CVMRuntimeException, CVMBlockReturnException
	{
		final CVMBlock self = checkClassHandling (aVM, CVMBlock.class, aInstance);
		
		if( aMethod == "do" )
			return aVM.execute (self, aStack, 0);
		else if( aMethod == "do:")
			return aVM.execute (self, aStack, 1);
		else if( aMethod.startsWith ("doWith:") )
		{
			int n = 0, f = 3;
			do {
				n += 1;
				f = aMethod.indexOf ("and:", f+4);
			} while (f != -1);
			
			return aVM.execute (self, aStack, n);
		}
		else if( aMethod == "doUsing:" )
		{
			final Object aArray = aStack.at (1);
			if( aArray instanceof CVMArray )
				return aVM.execute (self, ((CVMArray)aArray).getJavaArray ());
			else if( aArray instanceof Object[] )
				return aVM.execute (self, (Object[]) aArray);
		}
		
		return getSuperclass (aVM).callInstance (aVM, aInstance, aMethod, aStack, nParams);
	}
	
	public I_ChattyClass getSuperclass (ChattyVM aVM)
	{
		return aVM.classFor (ChattyBasic.class);
	}
}
